{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[0, 0, 0, 2, 2],\n",
       "        [0, 0, 0, 3, 3],\n",
       "        [0, 0, 0, 1, 1],\n",
       "        [1, 1, 1, 0, 0],\n",
       "        [2, 2, 2, 0, 0],\n",
       "        [5, 5, 5, 0, 0],\n",
       "        [1, 1, 1, 0, 0]])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from numpy import *\n",
    "from numpy import linalg as la\n",
    "\n",
    "\n",
    "def loadExData():\n",
    "    return [[0, 0, 0, 2, 2], [0, 0, 0, 3, 3], [0, 0, 0, 1, 1], [1, 1, 1, 0, 0],\n",
    "            [2, 2, 2, 0, 0], [5, 5, 5, 0, 0], [1, 1, 1, 0, 0]]\n",
    "\n",
    "\n",
    "def loadExData2():\n",
    "    return [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0,\n",
    "             5], [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],\n",
    "            [0, 0, 0, 0, 4, 0, 0, 1, 0, 4,\n",
    "             0], [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],\n",
    "            [5, 4, 5, 0, 0, 0, 0, 5, 5, 0,\n",
    "             0], [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],\n",
    "            [4, 3, 4, 0, 0, 0, 0, 5, 5, 0,\n",
    "             1], [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],\n",
    "            [0, 0, 0, 2, 0, 2, 5, 0, 0, 1,\n",
    "             2], [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],\n",
    "            [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]\n",
    "\n",
    "\n",
    "def ecludSim(inA, inB):\n",
    "    return 1.0 / (1.0 + la.norm(inA - inB))\n",
    "\n",
    "\n",
    "def pearsSim(inA, inB):\n",
    "    if len(inA) < 3: return 1.0\n",
    "    return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]\n",
    "\n",
    "\n",
    "def cosSim(inA, inB):\n",
    "    num = float(inA.T * inB)\n",
    "    denom = la.norm(inA) * la.norm(inB)\n",
    "    return 0.5 + 0.5 * (num / denom)\n",
    "\n",
    "\n",
    "myMat = mat(loadExData())\n",
    "myMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.12973190755680383, 1.0)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ecludSim(myMat[:, 0], myMat[:, 4]), ecludSim(myMat[:, 0], myMat[:, 0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.5, 1.0)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cosSim(myMat[:, 0], myMat[:, 4]), cosSim(myMat[:, 0], myMat[:, 0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.20596538173840329, 1.0)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pearsSim(myMat[:, 0], myMat[:, 4]), pearsSim(myMat[:, 0], myMat[:, 0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# def standEst(dataMat, user, simMeas, item):\n",
    "#     n = shape(dataMat)[1]\n",
    "#     simTotal = 0.0\n",
    "#     ratSimTotal = 0.0\n",
    "#     for j in range(n):\n",
    "#         userRating = dataMat[user, j]\n",
    "#         if userRating == 0: continue\n",
    "#         overLap = nonzero(logical_and(dataMat[:,item].A>0, \\\n",
    "#                                       dataMat[:,j].A>0))[0]\n",
    "\n",
    "#         print('dataMat[:,item]=',dataMat[:,item])\n",
    "#         print('dataMat[:,j]=',dataMat[:,j])\n",
    "#         print('overLap=', overLap)\n",
    "\n",
    "#         if len(overLap) == 0: similarity = 0\n",
    "#         else:            similarity = simMeas(dataMat[overLap,item], \\\n",
    "#                     dataMat[overLap,j])\n",
    "#         print('the %d and %d similarity is: %f' % (item, j, similarity))\n",
    "#         simTotal += similarity\n",
    "#         ratSimTotal += similarity * userRating\n",
    "#     if simTotal == 0: return 0\n",
    "#     else: return ratSimTotal / simTotal\n",
    "\n",
    "\n",
    "def standEst(dataMat, user, simMeas, item):\n",
    "    n = shape(dataMat)[1]\n",
    "    simTotal = 0.0\n",
    "    ratSimTotal = 0.0\n",
    "    for j in range(n):\n",
    "        userRating = dataMat[user, j]\n",
    "        if userRating == 0: continue\n",
    "\n",
    "        overLap = []\n",
    "        for i in range(len(dataMat)):\n",
    "            if dataMat[i, item] > 0 and dataMat[i, j] > 0:\n",
    "                overLap.append(i)\n",
    "                \n",
    "        if len(overLap) == 0: similarity = 0\n",
    "        else:            similarity = simMeas(dataMat[overLap,item], \\\n",
    "       dataMat[overLap,j])\n",
    "        simTotal += similarity\n",
    "        ratSimTotal += similarity * userRating\n",
    "    if simTotal == 0: return 0\n",
    "    else: return ratSimTotal / simTotal\n",
    "\n",
    "\n",
    "def svdEst(dataMat, user, simMeas, item):\n",
    "    n = shape(dataMat)[1]\n",
    "    simTotal = 0.0\n",
    "    ratSimTotal = 0.0\n",
    "    U, Sigma, VT = la.svd(dataMat)\n",
    "    Sig4 = mat(eye(4) * Sigma[:4])\n",
    "    xformedItems = dataMat.T * U[:, :4] * Sig4.I\n",
    "    for j in range(n):\n",
    "        userRating = dataMat[user, j]\n",
    "        if userRating == 0 or j == item: continue\n",
    "        similarity = simMeas(xformedItems[item,:].T,\\\n",
    "                             xformedItems[j,:].T)\n",
    "        simTotal += similarity\n",
    "        ratSimTotal += similarity * userRating\n",
    "    if simTotal == 0: return 0\n",
    "    else: return ratSimTotal / simTotal\n",
    "\n",
    "\n",
    "def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):\n",
    "    unratedItems = nonzero(dataMat[user, :].A == 0)[1]\n",
    "    if len(unratedItems) == 0: return 'you rated everything'\n",
    "    itemScores = []\n",
    "    for item in unratedItems:\n",
    "        estimatedScore = estMethod(dataMat, user, simMeas, item)\n",
    "        itemScores.append((item, estimatedScore))\n",
    "    return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[4, 4, 0, 2, 2],\n",
       "        [4, 0, 0, 3, 3],\n",
       "        [4, 0, 0, 1, 1],\n",
       "        [1, 1, 1, 0, 0],\n",
       "        [2, 2, 2, 0, 0],\n",
       "        [5, 5, 5, 0, 0],\n",
       "        [1, 1, 1, 0, 0]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myMat = mat(loadExData())\n",
    "myMat[0, 1] = myMat[0, 0] = myMat[1, 0] = myMat[2, 0] = 4\n",
    "myMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(2, 4.0), (1, 2.0)]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recommend(myMat, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(2, 4.0), (1, 2.8)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recommend(myMat, 2, simMeas=ecludSim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(2, 4.0), (1, 2.0)]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recommend(myMat, 2, simMeas=pearsSim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 3.333333333333333), (2, 3.3333333333333326)]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recommend(myMat, 1, estMethod=svdEst)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
